package com.itheima.sh.esdemo;

import com.alibaba.fastjson.JSON;
import com.itheima.sh.esdemo.pojo.User01;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;



/**
 * @Name: jsj
 * @Version: 1.0.0
 * @Date: 2020/11/24_20:08
 * @Description:
 */
public class testESday02 {

    //查询全部
    @Test
    public void testFindAll() throws Exception{
      //1. 创建SearchSourceBuilder对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //   1. 添加查询条件QueryBuilders
        searchSourceBuilder.query(
                QueryBuilders.matchAllQuery()
        );
        //2. 创建SearchRequest对象，并制定索引库名称
        SearchRequest searchRequest = new SearchRequest("user");
        //3. 添加SearchSourceBuilder对象到SearchRequest对象source中
        SearchRequest request = searchRequest.source(searchSourceBuilder);
        //4. 发起请求，得到结果
        SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        //5. 解析结果SearchResponse
        //   1. 获取总条数
        System.out.println( "总条数为:"+search.getHits().getTotalHits().value);
        //   2. 获取SearchHits数组，并遍历
        for (SearchHit hit : search.getHits()) {
            //* 获取其中的`_source`，是JSON数据   * 把`_source`反序列化为User对象
            User01 user01 = JSON.parseObject(hit.getSourceAsString(), User01.class);
            System.out.println("user01 = " + user01);
        }

    }


    //词条查询
    @Test
    public void testTerm() throws Exception{
        //1. 创建SearchSourceBuilder对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //   1. 添加查询条件QueryBuilders.termQuery()
        searchSourceBuilder.query(
                QueryBuilders.termQuery("name", "vivo")
        );
        //2. 创建SearchRequest对象，并制定索引库名称
        SearchRequest searchRequest = new SearchRequest("user");
        //3. 添加SearchSourceBuilder对象到SearchRequest对象source中
        SearchRequest source = searchRequest.source(searchSourceBuilder);
        //4. 发起请求，得到结果
        SearchResponse search = client.search(source, RequestOptions.DEFAULT);
        //5. 解析结果SearchResponse
        //   1. 获取总条数
        System.out.println(search.getHits().getTotalHits().value);
        //   2. 获取SearchHits数组，并遍历
        for (SearchHit hit : search.getHits()) {
            User01 user01 = JSON.parseObject(hit.getSourceAsString(), User01.class);
            System.out.println("user01 = " + user01);
        }
    }

    //条件查询
    @Test
    public void testMatch() throws Exception{
        //1. 创建SearchSourceBuilder对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //   1. 添加查询条件QueryBuilders.termQuery()
        searchSourceBuilder.query(
                QueryBuilders.matchQuery("brandName.keyword", "vivo")
        );
        //2. 创建SearchRequest对象，并制定索引库名称
        SearchRequest searchRequest = new SearchRequest("user");
        //3. 添加SearchSourceBuilder对象到SearchRequest对象source中
        SearchRequest source = searchRequest.source(searchSourceBuilder);
        //4. 发起请求，得到结果
        SearchResponse search = client.search(source, RequestOptions.DEFAULT);
        //5. 解析结果SearchResponse
        //   1. 获取总条数
        System.out.println("总条数为"+search.getHits().getTotalHits().value);
        //   2. 获取SearchHits数组，并遍历

        for (SearchHit hit : search.getHits()) {
            User01 user01 = JSON.parseObject(hit.getSourceAsString(), User01.class);
            System.out.println("user01 = " + user01);
        }
    }


    //模糊查询
    @Test
    public void testFuzzy() throws Exception{
        FuzzyQueryBuilder queryBuilder = QueryBuilders.fuzzyQuery("name", "oivv");
        queryBuilder.fuzziness(Fuzziness.TWO);//最大纠正次数为2
        query(queryBuilder);
    }

    //多条件查询
    @Test
    public void testFields() throws Exception{
        QueryStringQueryBuilder queryStringQueryBuilder = QueryBuilders.queryStringQuery("华为手机")
                .field("brandName")
                .field("categoryName")
                //.defaultField("note")  // 默认搜索域
                .defaultOperator(Operator.OR);
        query(queryStringQueryBuilder);
    }

    //范围 排序
    @Test
    public void testBool() throws Exception{
        RangeQueryBuilder queryBuilder = QueryBuilders.rangeQuery("price");
        queryBuilder.gte(10000);
        queryBuilder.lte(10010);
        query(queryBuilder);

    }

    //bool 查询 结果过滤   分页查询
    @Test
    public void testBoolFilter() throws Exception{
        //构建bool 查询
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //构建分词查询
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "登机新款");
        //boolQueryBuilder.should()
        boolQueryBuilder.must(matchQueryBuilder);
       // boolQueryBuilder.mustNot()

        //构建过滤
        MatchQueryBuilder price = QueryBuilders.matchQuery("price", "73100");
        RangeQueryBuilder num = QueryBuilders.rangeQuery("num")
                .gte(10000)
                .lte(11000);
        boolQueryBuilder.filter(price);
        boolQueryBuilder.filter(num);

        query(boolQueryBuilder);

    }








    public void query(QueryBuilder queryBuilder) throws Exception{
        //1. 创建SearchSourceBuilder对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //   1. 添加查询条件QueryBuilders.termQuery()
        searchSourceBuilder.query(queryBuilder);

        //排序
        searchSourceBuilder.sort("num", SortOrder.DESC);
        searchSourceBuilder.sort("categoryId", SortOrder.ASC);

        //分页
        int page = 1;
        int size=5;
        int from=(page-1)*size;
        searchSourceBuilder.from(from);
        searchSourceBuilder.size(size);

        //高亮
        HighlightBuilder highlighter = SearchSourceBuilder.highlight();
        highlighter.field("name");  // 高亮显示域
        highlighter.preTags("<font color='red'>");  // 高亮显示前缀
        highlighter.postTags("</font>");   // 高亮显示后缀
        searchSourceBuilder.highlighter(highlighter);

        //2. 创建SearchRequest对象，并制定索引库名称
        SearchRequest searchRequest = new SearchRequest("user");
        //3. 添加SearchSourceBuilder对象到SearchRequest对象source中
        SearchRequest source = searchRequest.source(searchSourceBuilder);
        //4. 发起请求，得到结果
        SearchResponse search = client.search(source, RequestOptions.DEFAULT);

        //5. 解析结果SearchResponse
        //   1. 获取总条数
        System.out.println("总条数为"+search.getHits().getTotalHits().value);
        //   2. 获取SearchHits数组，并遍历
        for (SearchHit hit : search.getHits()) {
            User01 user01 = JSON.parseObject(hit.getSourceAsString(), User01.class);

            //解析高亮部分
            HighlightField highlightField = hit.getHighlightFields().get("name");
            Text[] fragments = highlightField.getFragments();
            String name = StringUtils.join(fragments);
            if(StringUtils.isNotBlank(name)){
                user01.setName(name);
            }

            System.out.println("user01 = " + user01);
        }
    }


    //连接es
    RestHighLevelClient client ;
    @Before
    public void before() throws Exception{
        client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("192.168.200.129", 9200, "http")
                )
        );
    }

    //关闭es
    @After
    public void after() throws Exception{
        client.close();
    }
}
